package com.qqt.csr.common.utils;

import com.qqt.csr.common.exception.BaseException;
import com.qqt.csr.common.exception.StatusCode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.function.Supplier;

/**
 * @author:
 * @date: 2024-05-27 15:55
 */
@Slf4j
@Component
@AllArgsConstructor
public class TransactionUtil {
    private final PlatformTransactionManager txManager;

    public <T> T execute(Supplier<T> supplier) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        TransactionStatus status = txManager.getTransaction(def);
        try {
            T result = supplier.get();
            txManager.commit(status);
            return result;
        }catch (BaseException e){
            txManager.rollback(status);
            throw e;
        }catch (Throwable e) {
            txManager.rollback(status);
            log.error("TransactionUtil execute error!", e);
            throw new BaseException(StatusCode.Common.INTERNAL_SERVER_ERROR, e);
        }
    }

    public void execute(Runnable runnable) {
        execute(()->{
            runnable.run();
            return null;
        });
    }
}
